const {
  override,
  fixBabelImports,
  addWebpackAlias,
  addWebpackPlugin,
  disableEsLint,
  addWebpackResolve,
  overrideDevServer,
  addPostcssPlugins,
  watchAll,
  setWebpackOptimizationSplitChunks,
  adjustStyleLoaders,
  addWebpackModuleRule,
  addLessLoader
} = require('customize-cra')
const NodePolyfillPlugin = require("node-polyfill-webpack-plugin")
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const path = require('path')

function resolve(dir) {
  return path.join(__dirname, dir)
}

/**
 * @param target: 要遍历的对象
 * @param name: 插件名
 * @param callback: 回调函数，第一个参数为该插件对象
 * @return null
 */
function invade(target, name, callback) {
  target.forEach(
    item => {
      if (item.constructor.name === name) {
        callback(item)
      }
    }
  )
}

const devServerConfig = () => config => {
  config.proxy = {
    '/api': {
      // target: 'http://10.20.20.206:9133', //徘徊本地
      target: 'http://192.168.3.165:9109', //测试环境
      // target: 'http://10.20.20.164:9111', //正式环境
      changeOrigin: true,
      secure: false,
      pathRewrite: {
        '^/api': ''
      }
    }
  }
  return config
}
const chunks = process.env.NODE_ENV === "production" ? 'all' : 'async'
const splitChunks = {
  chunks: chunks,
  minSize: 100 * 1024,
  minChunks: 1, //拆分前必须共享模块的最小块数。
  maxAsyncRequests: 5, //按需加载时并行请求的最大数目。
  maxInitialRequests: 3, //入口点的最大并行请求数
  cacheGroups: {
    reactVendor: {
      test: /[\\/]node_modules[\\/](react|react-dom|react-dom-router|babel-polyfill|react-redux|toolkit|redux|prop-types)/,
      name: 'react',
      priority: 40,
      reuseExistingChunk: true,
    },
    antdVendor: {
      test: (module) => {
        return /ant|axios|icons|moment/.test(module.context);
      },
      name: 'ant-design',
      priority: 30,
      reuseExistingChunk: true,
    },
    vendors: {
      test: /[\\/]node_modules[\\/]/,
      name: 'vendors',
      priority: 20,
      reuseExistingChunk: true,
    },
    componentsVendor: {
      test: resolve('src/components'),
      name: 'components',
      priority: 10,
      reuseExistingChunk: true
    },
  }
}

const customConfig = () => config => {
  if (process.env.NODE_ENV === "production") {
    config.devtool = false;
    config.mode = 'production';
    invade(config.optimization.minimizer, 'TerserPlugin', (e) => {
      // 去除注释
      e.options.extractComments = false
      // 去除生产环境 console.log和debugger
      e.options.minimizer.options.compress.drop_console = true
      e.options.minimizer.options.compress.drop_debugger = true
      e.options.minimizer.options.compress.pure_funcs = ['console.log']
    })

    // 修改打包后 js 文件名
    // console.log(config.output.chunkFilename); //static/js/[name].[contenthash:8].chunk.js //output.chunkFilename 决定了非入口(non-entry) chunk 文件的名称
    // console.log(config.output.filename); //static/js/[name].[contenthash:8].js //output.filename 决定了每个入口(entry) 输出 bundle 的名称
    config.output.filename = 'static/js/[name].[contenthash:8].bundle.js'
    config.output.chunkFilename = 'static/js/[name].[contenthash:8].chunk.js'
    config.output.assetModuleFilename = 'static/media/[name].[contenthash:8][ext]'

    // 修改打包后 css 文件名
    invade(config.plugins, 'MiniCssExtractPlugin', (e) => {
      // console.log(e.options.chunkFilename); //  static/css/[name].[contenthash:8].chunk.css
      e.options.filename = 'static/css/[name].[contenthash:8].bundle.css'
      e.options.chunkFilename = function (module) {
        return 'static/css/[name].[contenthash:8].chunk.css'
      }
      e.options.ignoreOrder = true
    })

  }
  return config
}

const postcssStyleLoaders = (rule) => {
  const [, css, postcss, resolve, processor] = rule.use
  const postcssOptions = postcss.options;
  const cssOptions = css.options;
  if (postcssOptions) {

    postcss.options = {
      postcssOptions,
      sourceMap: false
    };
  }
  if (cssOptions) {
    css.options = {
      ...cssOptions,
    };

  }
}

const lessModuleRule = {
  test: [/\.less$/],
  use: ['css-loader', 'postcss-loader', {
    loader: 'less-loader'
  }]
}

module.exports = {
  webpack: override(
    // antd样式按需引用
    fixBabelImports('import', {
      libraryName: 'antd',
      libraryDirectory: 'es',
      style: 'css',
    }),
    addPostcssPlugins([
      require('postcss-preset-env')({
        stage: 0
      })
    ]),
    addWebpackPlugin(new NodePolyfillPlugin()),
    // addWebpackPlugin(new BundleAnalyzerPlugin()),
    // 路径别名
    addWebpackAlias({
      ['@']: path.resolve(__dirname, 'src'),
    }),
    // 禁用eslint
    disableEsLint(),
    // 使用nodejs的path
    addWebpackResolve({
      fallback: {
        
      }
    }),
    customConfig(),
    setWebpackOptimizationSplitChunks(splitChunks),
    adjustStyleLoaders(postcssStyleLoaders),
    addLessLoader(),
    addWebpackModuleRule(lessModuleRule),
  ),
  devServer: overrideDevServer(
    devServerConfig(),
    watchAll()
  )
}